home *** CD-ROM | disk | FTP | other *** search
- Path: news.pix.za!usenet
- From: js000021@pixie.co.za (Smit JS)
- Newsgroups: comp.lang.c
- Subject: Re: CPU time measurement
- Date: Wed, 10 Jan 1996 07:06:44 GMT
- Organization: PiX - Proxima information X-change
- Message-ID: <4d06ks$p7j@hawk.pix.za>
- References: <4cs60j$ilb@azure.acsu.buffalo.edu>
- NNTP-Posting-Host: 196.23.60.105
- X-Newsreader: Forte Free Agent 1.0.82
-
- naras-r@acsu.buffalo.edu (Ram Prasad) wrote:
-
- >Hi,
-
- >Is there a standard acceptable way of measuring the
- >number of (milli)seconds that different pieces of code take
- >to execute in a system?
-
- >I want to know the times taken by different subroutines
- >in my code. (I am looking for something that will give
- >the time to execute without interference from other
- >processes and programs that may be running in the system)
-
- >I found "getrusage" in the man pages, but I am not sure if
- >that's what I should use.
-
- >thanks,
-
-
- >--
- >Ram
- >--
- >Ram Prasad naras-r@acsu.buffalo.edu
-
- Hi Ram,
- The following works well. I cannot remember where I got it from.
- Johan Smit
- js000021@pixie.co.asm
- public _start
- public _stop
- ;use with _stop.asm from C
- ;/*--------------------------------------------------------*/
- ;/*----------------Use in C file---------------------------*/
- ;
- ;extern void start();
- ;extern void stop();
- ;
- ;unsigned int timer_sec,timer_milli,timer_micro,tick_count,adjustm=29;
- ;/*adjustm to be adjusted for a machine. Set adjustm to 0 and call
- start()
- ;and stop() with no intervening code. Set the resultant value into
- adjustm*/
- ; start();
- ;routines to time here
- ; stop();
- ; printf(" %d.%3.3d%3.3d secs\n",timer_sec,timer_milli,timer_micro);
- ;/*----------------Use in C file---------------------------*/
- ;/*--------------------------------------------------------*/
-
- extrn _timer_sec:word
- extrn _timer_milli:word
- extrn _timer_micro:word
- extrn _tick_count:word
- extrn _adjustm:word
-
- timer_low equ ds:[006ch]
- bios_dataseg equ 0040h
- timer_mode equ 43h
- timer0 equ 40h
-
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:_TEXT,DS:DGROUP
- ;/*--------------------------------------------------------*/
- ;/*---------------------_start-----------------------------*/
- _start proc near
- ;Called from C small model to determine time taken by a function
- ;call _start at start of function
- ;call _stop at end of function
-
- push ax
- push dx
- push ds
- mov _timer_micro,0 ;reset variables
- mov _timer_milli,0
- mov _timer_sec,0
- ;/*------------Initialise counter of 8253------------------*/
- ;note timer mode changed from mode 3 to mode 2. The timer period and
- interrupt
- ;functions are unaffected, the 8259 is initialised to be edge
- sensitive.
- ;The counter now decrement by 1
- mov al,00110100b ;ctr0,lsb then msb,mode2 binary
- out timer_mode,al ;mode register of 8253
- sub ax,ax ;0 results in max count
- out timer0,al ;lsb
- out timer0,al ;msb
- ;/*------------Read bios time-of-day-----------------------*/
- mov dx,bios_dataseg
- mov ds,dx
- mov ax,timer_low ;get count
- pop ds ;back to this dataseg
- mov _tick_count,ax
- pop dx
- pop ax
- ret
- _start endp
- ;/*--------------------------_start-----------------------*/
- ;/*-------------------------------------------------------*/
- ;/*--------------------------_stop------------------------*/
- _stop PROC near
- push ax
- push bx
- push dx
- push ds ;save dataseg
- ;elapsed time since _timer_start consists of:
- ; (1) timer count intervals of 840ns
- ; (2) interrupt ticks of 55ms
- ;/*-----------------read counter 0 of 8253-----------------*/
- mov al,0 ;latch counter for read
- cli ;int off until bios tod is read
- out timer_mode,al ;8253 mode register
- in al,timer0
- mov dl,al
- in al,timer0
- mov dh,al ;dx now have the count
- ;/*----------calculate the timer_micro component-----------*/
- mov ax,65535 ;maxcount
- sub ax,dx ;timer count
- mul timer_convert ;838.096 ns per count
- div tenthousand ;time in microsecs
- mov _timer_micro,ax ;save microsecs,rounded to nsec
- cmp dx,5000
- jb cont ;round down
- inc _timer_micro ;round up
- ;*/-----------------get bios time of day-------------------*/
- cont: mov dx,bios_dataseg
- mov ds,dx
- mov ax,timer_low ;get the reading
- pop ds ;back to this dataseg
- sti ;interrupts on
- sub ax,_tick_count ;_timer_start reading
- mul count_convert ;54.925 msec per tick
- div thousand
- mov count_milli,ax ;save millisec part
- mov count_micro,dx ;save microsec part
- ;/*----------------------check for jitter------------------*/
- cmp ax,0 ;check if elapsed time is 'small'
- jne jitter_ok ;no problem
- mov ax,_adjustm
- cmp _timer_micro,ax
- jae jitter_ok ;if no jitter,ok
- mov _timer_micro,ax ;else -ve time, so fix
- ;/*-Combine timer and count values,result in time variables-*/
- jitter_ok:
- mov ax,dx ;get count_micro
- add ax,_timer_micro ;sum micro fields
- cmp ax,_adjustm ;check for underflow
- jae compensate ; no problem
- dec count_milli ;borrow
- add ax,1000
- compensate:
- sub ax,_adjustm ;compensate for time delays
- mov _timer_micro,ax
- cmp ax,1000 ;check for overflow
- jb field_ok
- sub dx,dx ;timer_micro field too large
- div thousand ;so carry out into timer_milli
- mov _timer_milli,ax
- mov _timer_micro,dx
- field_ok:
- mov ax,count_milli ;sum milli fields
- add _timer_milli,ax
- cmp _timer_milli,1000;check for overflow
- jb done
- sub dx,dx
- mov ax,_timer_milli
- div thousand
- mov _timer_sec,ax
- mov _timer_milli,dx
- done: pop dx
- pop bx
- pop ax
- ret
- _STOP endp
- ;/*------------------------_stop---------------------------*/
- ;/*--------------------------------------------------------*/
-
- _TEXT ENDS
-
- DGROUP GROUP _DATA,_BSS
- _DATA SEGMENT WORD PUBLIC 'DATA'
- ;initialised data segment
- timer_convert dw 8381 ;838.096 nsec per count
- count_convert dw 54925 ;54.925 msec per tick
- tenthousand dw 10000
- thousand dw 1000
-
- _DATA ENDS
- _BSS SEGMENT WORD PUBLIC 'BSS'
- ;uninitialised data segment
-
- count_micro dw ? ;calc from interrupt ticks
- count_milli dw ? ;calc from interrupt ticks
-
-
- _BSS ENDS
- END
-
-